class SearchController < ApplicationController
    
    layout 'default'
    
    def initialize
        @didily_limit = 50
    end
    
    #########################################################
    # Show search page if there is nothing specified to search for
    # or if there are searchable params search for them
    def index
        if request.post?
            if params[:form_terms].nil? or params[:form_terms].empty?
                flash[:message] = 'Please enter something to search for.'
            else
                redirect_to '/search/search_results?terms=' + URI.escape(params[:form_terms])
            end
        end
    end
    
    #########################################################
    # search all fields for the given terms
    def search_results
        if request.post?
            if params[:form_terms].nil? or params[:form_terms].empty?
                flash[:message] = 'Please enter something to search for.'
                render_search
            else
                redirect_to '/search/search_results?terms=' + URI.escape(params[:form_terms])
            end
        else
            @current_uri = '/search/search_results'
            @url_terms = '?terms='
            if not params[:terms].nil? and not params[:terms].empty?
                @url_terms += URI.escape(params[:terms])
            end
            do_search(:all)
        end
    end
    
    #########################################################
    # search destination and source uris
    def uris
        if request.post?
            if params[:form_terms].nil? or params[:form_terms].empty?
                flash[:message] = 'Please enter a uri to search for.'
                render_search
            else
                redirect_to '/search/uris?terms=' + URI.escape(params[:form_terms])
            end
        else
            @current_uri = '/search/uris'
            @url_terms = '?terms='
            if not params[:terms].nil?
                @url_terms += URI.escape(params[:terms])
            end
            do_search(:uris)
        end
    end
    
    #########################################################
    # search destination and source uris
    def learningsupport
        if request.post?
            if params[:form_terms].nil? or params[:form_terms].empty?
                flash[:message] = 'Please enter a uri to search for.'
                render_search
            else
                redirect_to '/search/uris?terms=' + URI.escape(params[:form_terms])
            end
        else
            @current_uri = '/search/learningsupport'
            @url_terms = '?terms='
            if not params[:terms].nil?
                @url_terms += URI.escape(params[:terms])
            end
             @terms = params[:terms].collect {|term| term}
             sql_terms = params[:terms].collect {|term| "%" + term + "%"}.join(' OR ')
            
            
           
            search_conditions = 'SELECT didilies.*, users.login, relationships.name, from_links.uri, to_links.uri FROM didilies ' 
            search_conditions << 'INNER JOIN users ON users.id = didilies.user_id '
            search_conditions << 'INNER JOIN relationships ON relationships.id = didilies.relationship_id '
            search_conditions << 'INNER JOIN links from_links ON from_links.id = didilies.from_id '
            search_conditions << 'INNER JOIN links to_links ON to_links.id = didilies.to_id '
            search_conditions << 'WHERE ((from_links.uri LIKE ? )) AND ((to_links.uri LIKE ? ))'
            search_conditions << 'ORDER BY didilies.created_at DESC '
            sql_term_array = [sql_terms , "%http://serc.carleton.edu/%"]
            #breakpoint
            @results = Didily.find_by_sql([search_conditions] + sql_term_array)
            #breakpoint
            if @results.length <= 0
                #There are no didilies for this page ... render nothing
                @page_title = "No Didily Found for: " + @terms.to_sentence
                self.render_results
            else
                #we know we have didilies now to reverse search on them
              counter =0  
              @results.each do |didily|
                  
                  @selecturi = didily.uri
                  search_conditions = 'SELECT didilies.*, users.login, relationships.name, from_links.uri, to_links.uri FROM didilies ' 
                  search_conditions << 'INNER JOIN users ON users.id = didilies.user_id '
                  search_conditions << 'INNER JOIN relationships ON relationships.id = didilies.relationship_id '
                  search_conditions << 'INNER JOIN links from_links ON from_links.id = didilies.from_id '
                  search_conditions << 'INNER JOIN links to_links ON to_links.id = didilies.to_id '
                  search_conditions << 'WHERE ((to_links.uri = ? ))'
                  search_conditions << 'ORDER BY didilies.created_at DESC '
                  sql_term_array = [didily.uri]
                  @combine = Didily.find_by_sql([search_conditions] + sql_term_array)
                  #breakpoint
                  if counter == 0 
                    @didilies = @combine
                    counter = 1 
                  else
                    @didilies = @didilies + @combine
                  end
                  
                  
                  
                end
                
                @page_title = "Didily for: " + @terms.to_sentence
                self.render_results
            end
            
                
            #do_search(:destination_uri)
        end
    end
    
    #########################################################
    # search destination uris
    def destination_uri
        if request.post?
            if params[:form_terms].nil? or params[:form_terms].empty?
                flash[:message] = 'Please enter a destination uri to search for.'
                render_search
            else
                redirect_to '/search/destination_uri?terms=' + URI.escape(params[:form_terms])
            end
        else
            @current_uri = '/search/destination_uri'
            @url_terms = '?terms='
            if not params[:terms].nil?
                @url_terms += URI.escape(params[:terms])
            end
            do_search(:destination)
        end
    end
    
    #########################################################
    # search source uris
    def source_uri
        if request.post?
            if params[:form_terms].nil? or params[:form_terms].empty?
                flash[:message] = 'Please enter a source uri to search for.'
                render_search
            else
                redirect_to '/search/source_uri?terms=' + URI.escape(params[:form_terms])
            end
        else
            @current_uri = '/search/source_uri'
            @url_terms = '?terms='
            if not params[:terms].nil?
                @url_terms += URI.escape(params[:terms])
            end
            do_search(:source)
        end
    end
    
    #########################################################
    # search relationships
    def relations
        if request.post?
            if params[:form_terms].nil? or params[:form_terms].empty?
                flash[:message] = 'Please enter a relation to search for.'
                render_search
            else
                redirect_to '/search/relations/' + escape_terms(params[:form_terms])
            end
        else
            @current_uri = '/search/relations'
            @url_terms = '/' + escape_terms(params[:terms]) unless params[:terms].nil?
            do_search(:relations)
        end
    end
    
    protected
    
    #########################################################
    # escape a parameter array
    def escape_terms(terms)
        if terms
            terms.collect {|term| URI.escape(term)}.join('/')
        else
        
        end
    end
    
    #########################################################
    # search all fields for the given terms
    def do_search(search_type = :all)
        
        if nil != params[:terms] && params[:terms].length > 0
            @terms = params[:terms].collect {|term| term}
            sql_terms = params[:terms].collect {|term| "%" + term + "%"}.join(' OR ')

            search_conditions = 'SELECT didilies.*, users.login, relationships.name, from_links.uri, to_links.uri FROM didilies ' 
            search_conditions << 'INNER JOIN users ON users.id = didilies.user_id '
            search_conditions << 'INNER JOIN relationships ON relationships.id = didilies.relationship_id '
            search_conditions << 'INNER JOIN links from_links ON from_links.id = didilies.from_id '
            search_conditions << 'INNER JOIN links to_links ON to_links.id = didilies.to_id '
                
            if search_type == :all
                search_conditions << 'WHERE ((relationships.name LIKE ? ) OR (didilies.from_title LIKE ? ) '
                search_conditions << 'OR (from_links.uri LIKE ? ) OR (to_links.uri LIKE ? ) OR (didilies.to_title LIKE ? )) ' 
                sql_term_array = [sql_terms, sql_terms, sql_terms, sql_terms, sql_terms]
                
            elsif search_type == :uris
                search_conditions << 'WHERE ((from_links.uri LIKE ? ) OR (to_links.uri LIKE ? )) ' 
                sql_term_array = [sql_terms, sql_terms]
                
            elsif search_type == :destination_uri
                search_conditions << 'WHERE ((to_links.uri LIKE ? )) ' 
                sql_term_array = [sql_terms]
                
            elsif search_type == :destination
                search_conditions << 'WHERE ((to_links.uri LIKE ? ) OR (didilies.to_title LIKE ? )) ' 
                sql_term_array = [sql_terms, sql_terms]
                                
            elsif search_type == :source_uri
                search_conditions << 'WHERE ((from_links.uri LIKE ? )) ' 
                sql_term_array = [sql_terms]
                
            elsif search_type == :source
                search_conditions << 'WHERE ((from_links.uri LIKE ? ) OR (didilies.from_title LIKE ? )) ' 
                sql_term_array = [sql_terms, sql_terms]
                                
            elsif search_type == :relations
                search_conditions << 'WHERE ((relationships.name LIKE ? )) ' 
                sql_term_array = [sql_terms]
            else
                
            end

            search_conditions << 'ORDER BY didilies.created_at DESC '
            search_conditions << 'LIMIT ' + @didily_limit.to_s
            @didilies = Didily.find_by_sql([search_conditions] + sql_term_array)
            
            if @didilies.length <= 0
                @page_title = "No Didily Found for: " + @terms.to_sentence
            else
                @page_title = "Didily for: " + @terms.to_sentence
            end
            
        else
            if params[:terms].nil?
                @page_title = 'No didily found for: ' + params[:terms]
            else
                @page_title = 'If you want me to find something you have to tell me what to look for.'
            end
            @didilies = []
        end
                
        self.render_results
    end

    #########################################################
    # all the results are rendered the same
    def render_search
        respond_to do |format|
            format.html { render :template => '/search/index' }
            format.xml  { render :xml => flash.to_xml }
            format.rss  { render :xml => flash.to_xml }
            format.atom  { render :xml => flash.to_xml }
            format.rdf  { render :xml => flash.to_xml }
        end
    end
        
    #########################################################
    # all the results are rendered the same
    def render_results
        respond_to do |format|
            format.html { render :template => '/search/results' }
            format.xml  { render :action => '../shared/didilies_xml.rxml', :layout=>false }
            format.rss  { render :action => '../shared/didilies_rss.rxml', :layout=>false }
            format.atom { render :action => '../shared/didilies_atom.rxml', :layout=>false }
            format.rdf  { render :action => '../shared/didilies_rdf.rxml', :layout=>false }
        end
    end
    
    ##########################################################
    # generates the sql for a condition based on terms
    def generate_terms_clause(terms, field)
        sql = ''
        if terms.length > 0
            
            # add wild cards to the terms so the user doesn't have to get an exact match
            terms = terms.collect {|term| "?"}
            
            # generate sql for terms in where clause
            
            terms_sql = " " + terms.join("' AND " + field + " like '") +  " "
            sql << field + " LIKE " + terms_sql
            
        end
        sql
    end
    
end
